#include "GS_Play.h"
#include "GameCore\Game.h"
#include "GameCore\GS_Loading_Template.h"
#include "GameCore\Texture.h"

#include "GameCore/SoundEngine/SoundManager.h"
#include "GameObjects\EnemyShip.h"

void GS_Play::Init()
{
	DXDevice::GetInstance()->SetProjectionOrthoMatrix(0.0f, DXDevice::GetInstance()->GetWidth(), 0.0f, DXDevice::GetInstance()->GetHeight(),1,1000);
	DXDevice::GetInstance()->SetViewMatrix(0.0f,0.0f,-91.0f,
												0.0f,0.0f,1.0f,
												0.0f,1.0f,0.0f);
	//---------------------------------------
	SpriteManager::GetInstance()->SetDirectory("Assets\\Sprites\\");
	TextureManager::GetInstance()->SetDirectory("Assets\\Textures\\");
	GS_Loading_Template* gs_Loading = new GS_Loading_Template();
	
	LoadingManager::GetInstance()->AddLoadingTextFile("Assets\\Data\\Map.xml",&mapText);
	Game::GetInstance()->PushState(gs_Loading);

	SoundManager::GetInstance()->playBackgroundMusic("Assets\\mario_08-1-1.wav", true);
	distortionFX = new RenderTarget("distortionFX", 1024, 1024);
	LoadingManager::GetInstance()->AddLoadingBinaryFile("Assets\\XDAE\\jet.XDAE", &jetBuffer, &jetSize);
	
}
bool GS_Play::PostInit(int& step)
{
	if(step == 0)
	{
		jet = new XColladaDX();
		jet->InitFromXCollada(jetBuffer);
		map.Init("Map1",mapText.c_str());
		/*
		GameObjectFactory::ActiveAllShipInitialValue(false);
		for(std::vector<Wave>::iterator it = map.waves.begin();it<map.waves.end();it++)
		{
			for(std::vector<ShipInWave>::iterator it2 = (*it).ships.begin();it2<(*it).ships.end();it2++)
			{
				GameObjectFactory::ActiveShipInitialValue((*it2).name.c_str(), true);
			}
		}
		for(std::vector<ShipInitialValue>::iterator it = GameObjectFactory::shipInitialValueList.begin(); it<GameObjectFactory::shipInitialValueList.end();it++)
		{
			if((*it).active)
			{
				(*it).sprite = SpriteManager::GetInstance()->LoadSpriteFromXMLFile((*it).spriteName);
			}
		}
		*/
	}
	else if(step == 1)
	{
		ShaderManager::GetInstance()->LoadVertexShaderFromFile("Simple_VS.cso");
		ShaderManager::GetInstance()->LoadPixelShaderFromFile("Simple_PS.cso");
		//ShaderManager::GetInstance()->LoadVertexShaderFromFile("Tex1_Diffuse_VS.cso");
		//ShaderManager::GetInstance()->LoadPixelShaderFromFile("Tex1_Diffuse_PS.cso");
		material_Tex1_Diffuse = new Material("Tex1_Diffuse");
		ShaderManager::GetInstance()->LoadVertexShaderFromFile("Tex1_Distortion_VS.cso");
		ShaderManager::GetInstance()->LoadPixelShaderFromFile("Tex1_Distortion_PS.cso");
		TextureManager::GetInstance()->LoadTexture("tex1.DDS");
		SpriteManager::GetInstance()->LoadSpriteFromXMLFile("ship.sprite");
		SpriteManager::GetInstance()->LoadSpriteFromFile("engine.txt");
	}
	else if(step == 2)
	{
		ship = new PlayerShip();
		ship->Init();
		return true;
	}
	
	step++;
	return false;
}
void GS_Play::Release()
{
	SafeDelete(ship);
	SafeDelete(jet);
	for (std::vector<Bullet*>::iterator it = playerBulletList.begin() ; it != playerBulletList.end(); ++it)
	{
		SafeDelete(*it);
	}
	playerBulletList.clear();
	SafeDelete(material_Tex1_Diffuse);
}
void GS_Play::Update(float timeTotal, float timeDelta)
{
	ship->UpdateInput();
	ship->Update(timeDelta);

	for (std::vector<Bullet*>::iterator it = playerBulletList.begin() ; it != playerBulletList.end();)
	{
		(*it)->Update(timeDelta);
		if((*it)->IsRemoved())
		{
			SafeDelete(*it);
			it = playerBulletList.erase(it);
		}
		else if((*it)->hp <= 0)
		{
			destroyedBulletList.push_back(*it);
			it = playerBulletList.erase(it);
		}
		else 
		{
			for (std::vector<Ship*>::iterator it2 = enemyShipList.begin() ; it2 != enemyShipList.end();)
			{
				if((*it)->hp > 0)
				{
					BoundGroup* bg1 = (*it)->GetDamageRegion();
					BoundGroup* bg2 = (*it2)->GetBodyRegion();
					b2Transform t1 = (*it)->GetBox2DTransform();
					b2Transform t2 = (*it2)->GetBox2DTransform();
					if(bg1->IsIntersectedWith(bg2, &t1, &t2))
					{
						(*it2)->Damaged((*it));
						(*it)->Hit();
					}
				}
				++it2;
			}
			++it;
		}
	}
	for (std::vector<Ship*>::iterator it = enemyShipList.begin() ; it != enemyShipList.end();)
	{
		if((*it)->IsRemoved())
		{
			SafeDelete(*it);
			it = enemyShipList.erase(it);
		}
		else
		{
			(*it)->Update(timeDelta);
			it++;
		}
	}
	if(ship->hp > 0)
	{
		for (std::vector<Ship*>::iterator it = enemyShipList.begin() ; it != enemyShipList.end();)
		{
			if((*it)->hp > 0)
			{
				BoundGroup* bg1 = ship->GetBodyRegion();
				BoundGroup* bg2 = (*it)->GetBodyRegion();
				b2Transform t1 = ship->GetBox2DTransform();
				b2Transform t2 = (*it)->GetBox2DTransform();
				if(bg1->IsIntersectedWith(bg2, &t1, &t2))
				{
					ship->Damaged((*it));
					(*it)->Damaged(ship);
					if((*it)->hp <= 0)
					{
						(*it)->Destroy();
					}
				}
			}
			++it;
		}
	}
	//spawn ship
	map.rowElapsed += map.rollSpeed*timeDelta;
	for(std::vector<Wave>::iterator it = map.waves.begin() + map.currentWave;it != map.waves.end();it++)
	{
		if((*it).row < map.rowElapsed)
		{
			map.currentWave++;
			for(std::vector<ShipInWave>::iterator it2 = (*it).ships.begin();it2 != (*it).ships.end();it2++)
			{
				Ship* enemy = (*it2).ship;
				enemy->SetPosition((*it2).x, (*it2).y);
				enemy->Init();
				enemyShipList.push_back(enemy);
			}
		}
		else
		{
			break;
		}
	}
}
void GS_Play::Render()
{
	float black[4] = {0,0,0,1};
	float red[4] = {1,0,0,1};
	float blue[4] = {0,0,1,1};
	//DXDevice::GetInstance()->PushRenderTarget(distortionFX);
	DXDevice::GetInstance()->ClearColorBuffer(black);
	DXDevice::GetInstance()->ClearDepthStencilBuffer();
	DXDevice::GetInstance()->SetProjectionPerspectiveMatrix(0.7,(float)DXDevice::GetInstance()->GetWidth()/(float)DXDevice::GetInstance()->GetHeight(),0.1,1000);
	float scale = 0.4f;
	DXDevice::GetInstance()->SetViewMatrix(200.0f,150.0f,-150.0f,
												0.0, 0.0, 0.0,
												0.0f,1.0f,0.0f);
	DXDevice::GetInstance()->SetDepthTest(true);
	DXDevice::GetInstance()->PushMatrix();
	//DXDevice::GetInstance()->Scale(scale,scale,scale);
	static float rotateX = 0.0f;
	rotateX += 0.02f;
	if(rotateX > 6.2832f)
	{
		rotateX -= 6.2832f;
	}
	DXDevice::GetInstance()->RotateAxis(rotateX, 0.0,1.0,0.0);
	DXDevice::GetInstance()->DrawXColladaDX(jet);
	DXDevice::GetInstance()->PopMatrix();
	DXDevice::GetInstance()->BeginDraw2D();
	//DXDevice::GetInstance()->SetActiveVertexShader(ShaderManager::GetInstance()->GetVertexShaderByFileName("Tex1_Diffuse_VS.cso"));
	//DXDevice::GetInstance()->SetActivePixelShader(ShaderManager::GetInstance()->GetPixelShaderByFileName("Tex1_Diffuse_PS.cso"));
	DXDevice::GetInstance()->SetActiveMaterial(material_Tex1_Diffuse);
	DXDevice::GetInstance()->SetBlend(FALSE);
	RectScreenF rectDes;
	rectDes.FromWidthHeight(-0.6,-1.0,1.2,2.0);
	RectScreenF rectScreenF;
	rectScreenF.FromWidthHeight(0,0,0.6,1);
	//DXDevice::GetInstance()->Draw2DTextureLogicalCoord(TextureManager::GetInstance()->GetTexture("tex1.DDS"), sampler
	//	, rectDes, rectScreenF);
	
	//DXDevice::GetInstance()->Draw2DTextureFullViewport(TextureManager::GetInstance()->GetTexture("tex1.DDS"));
	DXDevice::GetInstance()->SetBlend(TRUE);
	for (std::vector<Bullet*>::iterator it = playerBulletList.begin() ; it != playerBulletList.end(); ++it)
	{
		(*it)->Render();
	}
	for (std::vector<Ship*>::iterator it = enemyShipList.begin() ; it != enemyShipList.end();)
	{
		if((*it)->hp > 0)
		{
			(*it)->Render();
		}
		++it;
	}

	//ship->Render();
	
	DXDevice::GetInstance()->EndDraw2D();
	/*
	DXDevice::GetInstance()->PopRenderTarget();

	DXDevice::GetInstance()->ClearColorBuffer(black);
	DXDevice::GetInstance()->ClearDepthStencilBuffer();
	
	DXDevice::GetInstance()->BeginDraw2D();
	DXDevice::GetInstance()->SetActiveVertexShader(ShaderManager::GetInstance()->GetVertexShaderByFileName("Tex1_Distortion_VS"));
	DXDevice::GetInstance()->SetActivePixelShader(ShaderManager::GetInstance()->GetPixelShaderByFileName("Tex1_Distortion_PS"));
	DXDevice::GetInstance()->SetBlend(FALSE);

	rect3DF.FromWidthHeight(-0.6,1.0,1.2,2.0);
	rectScreenF.FromWidthHeight(0,0,0.6,1);
	DXDevice::GetInstance()->Draw2DTextureLogicalCoord(distortionFX->GetColorTexture()
		, rect3DF, rectScreenF);

	DXDevice::GetInstance()->EndDraw2D();
	*/

}
void GS_Play::AddPlayerBullet(Bullet* b)
{
	instance->playerBulletList.push_back(b);
}
void GS_Play::AddEnemyBullet(Bullet* b)
{
	instance->enemyBulletList.push_back(b);
}